home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / jove4.9 / part13 < prev    next >
Encoding:
Internet Message Format  |  1988-04-26  |  30.4 KB

  1. Subject:  v14i069:  Jove, an emacs variant, version 4.9, Part13/21
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
  7. Posting-number: Volume 14, Issue 69
  8. Archive-name: jove4.9/part13
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 13 (of 21)."
  17. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  18. if test -f './disp.c' -a "${1}" != "-c" ; then 
  19.   echo shar: Will not clobber existing file \"'./disp.c'\"
  20. else
  21. echo shar: Extracting \"'./disp.c'\" \(28346 characters\)
  22. sed "s/^X//" >'./disp.c' <<'END_OF_FILE'
  23. X/***************************************************************************
  24. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  25. X * is provided to you without charge, and with no warranty.  You may give  *
  26. X * away copies of JOVE, including sources, provided that this notice is    *
  27. X * included in all the files.                                              *
  28. X ***************************************************************************/
  29. X
  30. X#include "jove.h"
  31. X#include "ctype.h"
  32. X#include "termcap.h"
  33. X
  34. X
  35. X#ifdef MAC
  36. X#    include "mac.h"
  37. X#else
  38. X#    include <varargs.h>
  39. X#    include <sys/stat.h>
  40. X#endif
  41. X
  42. X#include <signal.h>
  43. X
  44. X#ifdef MAC
  45. X#    undef private
  46. X#    define private
  47. X#endif
  48. X
  49. X#ifdef    LINT_ARGS
  50. private void
  51. X#ifdef ID_CHAR
  52. X    DeTab(int, char *, char *, int, int),
  53. X    DelChar(int, int, int),
  54. X    InsChar(int, int, int, char *),
  55. X#endif
  56. X    DoIDline(int),
  57. X    do_cl_eol(int),
  58. X    ModeLine(Window *),
  59. X    mode_app(char *),
  60. X    GotoDot(void),
  61. X    UpdLine(int),
  62. X    UpdWindow(Window *, int);
  63. X
  64. private int
  65. X    AddLines(int, int),
  66. X    DelLines(int, int),
  67. X    UntilEqual(int);
  68. X#else
  69. private void
  70. X#ifdef ID_CHAR
  71. X    DeTab(),
  72. X    DelChar(),
  73. X    InsChar(),
  74. X#endif
  75. X    DoIDline(),
  76. X    do_cl_eol(),
  77. X    GotoDot(),
  78. X    ModeLine(),
  79. X    mode_app(),
  80. X    UpdLine(),
  81. X    UpdWindow();
  82. private int
  83. X    AddLines(),
  84. X    DelLines(),
  85. X    UntilEqual();
  86. X#endif    /* LINT_ARGS */
  87. X
  88. X#ifdef MAC
  89. X#    undef private
  90. X#    define private static
  91. X#endif
  92. X
  93. int    DisabledRedisplay = NO;
  94. X
  95. X/* Kludge windows gets called by the routines that delete lines from the
  96. X   buffer.  If the w->w_line or w->w_top are deleted and this procedure
  97. X   is not called, the redisplay routine will barf. */
  98. X
  99. void
  100. ChkWindows(line1, line2)
  101. Line    *line1;
  102. register Line    *line2;
  103. X{
  104. X    register Window    *w = fwind;
  105. X    register Line    *lp;
  106. X
  107. X    do {
  108. X        for (lp = line1->l_next; lp != line2->l_next; lp = lp->l_next) {
  109. X            if (lp == w->w_top)
  110. X                w->w_flags |= W_TOPGONE;
  111. X            if (lp == w->w_line)
  112. X                w->w_flags |= W_CURGONE;
  113. X        }
  114. X        w = w->w_next;
  115. X    } while (w != fwind);
  116. X}
  117. X
  118. extern int    RingBell;
  119. X
  120. void
  121. redisplay()
  122. X{
  123. X    extern int    AbortCnt;
  124. X    register Window    *w = fwind;
  125. X    int    lineno,
  126. X        done_ID = NO,
  127. X        i;
  128. X    register struct scrimage    *des_p,
  129. X                    *phys_p;
  130. X
  131. X    if (DisabledRedisplay == YES)
  132. X        return;
  133. X    curwind->w_line = curwind->w_bufp->b_dot;
  134. X    curwind->w_char = curwind->w_bufp->b_char;
  135. X#ifdef MAC
  136. X    InputPending = 0;
  137. X#else    
  138. X    if (InputPending = charp())    /* calls CheckEvent, which could */
  139. X        return;    /* result in a call to rediplay(). We don't want that. */
  140. X#endif
  141. X#ifdef JOB_CONTROL
  142. X    if (UpdFreq)
  143. X        sighold(SIGALRM);
  144. X#endif
  145. X    if (RingBell) {
  146. X        dobell(1);
  147. X        RingBell = 0;
  148. X    }
  149. X    AbortCnt = BufSize;        /* initialize this now */
  150. X    if (UpdMesg)
  151. X        DrawMesg(YES);
  152. X
  153. X    for (lineno = 0, w = fwind; lineno < ILI; w = w->w_next) {
  154. X        UpdWindow(w, lineno);
  155. X        lineno += w->w_height;
  156. X    }
  157. X
  158. X    UpdModLine = 0;    /* Now that we've called update window, we can
  159. X               assume that the modeline will be updated.  But
  160. X               if while redrawing the modeline the user types
  161. X               a character, ModeLine() is free to set this on
  162. X               again so that the modeline will be fully drawn
  163. X               at the next redisplay. */
  164. X
  165. X    des_p = DesiredScreen;
  166. X    phys_p = PhysScreen;
  167. X    for (i = 0; i < ILI; i++, des_p++, phys_p++) {
  168. X        if (!done_ID && (des_p->s_id != phys_p->s_id)) {
  169. X            DoIDline(i);
  170. X            done_ID = YES;
  171. X        }
  172. X        if ((des_p->s_flags & (DIRTY | L_MOD)) ||
  173. X            (des_p->s_id != phys_p->s_id) ||
  174. X            (des_p->s_vln != phys_p->s_vln) ||
  175. X            (des_p->s_offset != phys_p->s_offset))
  176. X            UpdLine(i);
  177. X        if (InputPending)
  178. X            goto ret;
  179. X    }
  180. X
  181. X
  182. X    if (Asking) {
  183. X        Placur(LI - 1, min(CO - 2, calc_pos(mesgbuf, Asking)));
  184. X            /* Nice kludge */
  185. X        flusho();
  186. X    } else
  187. X        GotoDot();
  188. ret:
  189. X#ifdef JOB_CONTROL
  190. X    if (UpdFreq)
  191. X        sigrelse(SIGALRM);
  192. X#else
  193. X    ;    /* yuck */
  194. X#endif
  195. X#ifdef MAC
  196. X    if(Windchange) docontrols();
  197. X#endif /* MAC */
  198. X}
  199. X
  200. X#ifndef IBMPC
  201. private void
  202. dobell(n)
  203. X{
  204. X    while (--n >= 0) {
  205. X#ifndef MAC
  206. X        if (VisBell && VB)
  207. X            putstr(VB);
  208. X        else
  209. X            putpad(BL, 1);
  210. X#else
  211. X        SysBeep(5);
  212. X#endif
  213. X    }
  214. X    flusho();
  215. X}
  216. X#endif /* IBMPC */
  217. X
  218. X/* find_pos() returns the position on the line, that C_CHAR represents
  219. X   in LINE */
  220. X
  221. int
  222. find_pos(line, c_char)
  223. Line    *line;
  224. X{
  225. X    return calc_pos(lcontents(line), c_char);
  226. X}
  227. X
  228. int
  229. calc_pos(lp, c_char)
  230. register char    *lp;
  231. register int    c_char;
  232. X{
  233. X    register int    pos = 0;
  234. X    register int    c;
  235. X
  236. X
  237. X    while ((--c_char >= 0) && ((c = *lp++) & CHARMASK) != 0) {
  238. X        if (c == '\t')
  239. X            pos += (tabstop - (pos % tabstop));
  240. X        else if (isctrl(c))
  241. X            pos += 2;
  242. X        else
  243. X            pos += 1;
  244. X     }
  245. X    return pos;
  246. X}
  247. X
  248. int    UpdModLine = 0,
  249. X    UpdMesg = 0,
  250. X    CanScroll = 0;
  251. X
  252. private void
  253. DoIDline(start)
  254. X{
  255. X    register struct scrimage    *des_p = &DesiredScreen[start];
  256. X    struct scrimage    *phys_p = &PhysScreen[start];
  257. X    register int    i,
  258. X            j;
  259. X
  260. X    /* Some changes have been made.  Try for insert or delete lines.
  261. X       If either case has happened, Addlines and/or DelLines will do
  262. X       necessary scrolling, also CONVERTING PhysScreen to account for the
  263. X       physical changes.  The comparison continues from where the
  264. X       insertion/deletion takes place; this doesn't happen very often,
  265. X       usually it happens with more than one window with the same
  266. X       buffer. */
  267. X
  268. X    if (!CanScroll)
  269. X        return;        /* We should never have been called! */
  270. X
  271. X    for (i = start; i < ILI; i++, des_p++, phys_p++)
  272. X        if (des_p->s_id != phys_p->s_id)
  273. X            break;
  274. X
  275. X    for (; i < ILI; i++) {
  276. X        for (j = i + 1; j < ILI; j++) {
  277. X            des_p = &DesiredScreen[j];
  278. X            phys_p = &PhysScreen[j];
  279. X            if (des_p->s_id != 0 && des_p->s_id == phys_p->s_id)
  280. X                break;
  281. X            if (des_p->s_id == PhysScreen[i].s_id) {
  282. X                if (des_p->s_id == 0)
  283. X                    continue;
  284. X                if (AddLines(i, j - i)) {
  285. X                    DoIDline(j);
  286. X                    return;
  287. X                }
  288. X                break;
  289. X            }
  290. X            if ((des_p = &DesiredScreen[i])->s_id == phys_p->s_id) {
  291. X                if (des_p->s_id == 0)
  292. X                    continue;
  293. X                if (DelLines(i, j - i)) {
  294. X                    DoIDline(i);
  295. X                    return;
  296. X                }
  297. X                break;
  298. X            }
  299. X        }
  300. X    }
  301. X}
  302. X
  303. X/* Make DesiredScreen reflect what the screen should look like when we are done
  304. X   with the redisplay.  This deals with horizontal scrolling.  Also makes
  305. X   sure the current line of the Window is in the window. */
  306. X
  307. int    ScrollAll = NO;
  308. X
  309. private void
  310. UpdWindow(w, start)
  311. register Window    *w;
  312. X{
  313. X    Line    *lp;
  314. X    int    i,
  315. X        upper,        /* top of window */
  316. X        lower,        /* bottom of window */
  317. X        strt_col,    /* starting print column of current line */
  318. X        ntries = 0;    /* # of tries at updating window */
  319. X    register struct scrimage    *des_p,
  320. X                    *phys_p;
  321. X    Buffer    *bp = w->w_bufp;
  322. X
  323. retry:
  324. X    if (w->w_flags & W_CURGONE) {
  325. X        w->w_line = bp->b_dot;
  326. X        w->w_char = bp->b_char;
  327. X    }
  328. X    if (w->w_flags & W_TOPGONE)
  329. X        CentWind(w);    /* reset topline of screen */
  330. X    w->w_flags &= ~(W_CURGONE | W_TOPGONE);
  331. X
  332. X    /* make sure that the current line is in the window */
  333. X    upper = start;
  334. X    lower = upper + w->w_height - 1;    /* don't include modeline */
  335. X    for (i = upper, lp = w->w_top; i < lower && lp != 0; lp = lp->l_next, i++)
  336. X        if (lp == w->w_line)
  337. X            break;
  338. X    if (i == lower || lp == 0) {
  339. X        ntries += 1;
  340. X        if (ntries == 1) {
  341. X            CalcWind(w);
  342. X            goto retry;
  343. X        } else if (ntries == 2) {
  344. X            w->w_top = w->w_line = w->w_bufp->b_first;
  345. X            printf("\rERROR in redisplay: I got hopelessly lost!");
  346. X            dobell(2);
  347. X            goto retry;
  348. X        } else if (ntries == 3) {
  349. X            printf("\n\rOops, still lost, quitting ...\r\n");
  350. X            finish(1);
  351. X        }
  352. X    }
  353. X
  354. X    /* first do some calculations for the current line */
  355. X    {
  356. X        int    diff = (w->w_flags & W_NUMLINES) ? 8 : 0,
  357. X            end_col;
  358. X
  359. X        strt_col = (ScrollAll == YES) ? w->w_LRscroll :
  360. X               PhysScreen[i].s_offset;
  361. X        end_col = strt_col + (CO - 2) - diff;
  362. X        /* Right now we are displaying from strt_col to
  363. X           end_col of the buffer line.  These are PRINT
  364. X           columns, not actual characters. */
  365. X        w->w_dotcol = find_pos(w->w_line, w->w_char);
  366. X        /* if the new dotcol is out of range, reselect
  367. X           a horizontal window */
  368. X        if ((PhysScreen[i].s_offset == -1) ||
  369. X            (w->w_dotcol < strt_col) ||
  370. X            (w->w_dotcol >= end_col)) {
  371. X            if (w->w_dotcol < ((CO - 2) - diff))
  372. X                strt_col = 0;
  373. X            else
  374. X                strt_col = w->w_dotcol - (CO / 2);
  375. X            if (ScrollAll == YES) {
  376. X                if (w->w_LRscroll != strt_col)
  377. X                    UpdModLine = YES;
  378. X                w->w_LRscroll = strt_col;
  379. X            }
  380. X        }
  381. X        w->w_dotline = i;
  382. X        w->w_dotcol += diff;
  383. X    }
  384. X
  385. X    des_p = &DesiredScreen[upper];
  386. X    phys_p = &PhysScreen[upper];
  387. X    for (i = upper, lp = w->w_top; lp != 0 && i < lower; i++, des_p++, phys_p++, lp = lp->l_next) {
  388. X        des_p->s_window = w;
  389. X        des_p->s_lp = lp;
  390. X        des_p->s_id = lp->l_dline & ~DIRTY;
  391. X        des_p->s_flags = isdirty(lp) ? L_MOD : 0;
  392. X        if (w->w_flags & W_NUMLINES)
  393. X            des_p->s_vln = w->w_topnum + (i - upper);
  394. X        else
  395. X            des_p->s_vln = 0;
  396. X
  397. X        if (lp == w->w_line)
  398. X            des_p->s_offset = strt_col;
  399. X        else
  400. X            des_p->s_offset = w->w_LRscroll;
  401. X    }
  402. X
  403. X    /* Is structure assignment faster than copy each field separately? */
  404. X    if (i < lower) {
  405. X        static struct scrimage    dirty_plate = { 0, DIRTY, 0, 0, 0, 0 },
  406. X                    clean_plate = { 0, 0, 0, 0, 0, 0 };
  407. X
  408. X        for (; i < lower; i++, des_p++, phys_p++)
  409. X            if (phys_p->s_id != 0)
  410. X                *des_p = dirty_plate;
  411. X            else
  412. X                *des_p = clean_plate;
  413. X    }
  414. X
  415. X    des_p->s_window = w;
  416. X    des_p->s_flags = 0;
  417. X    if (((des_p->s_id = (int) w->w_bufp) != phys_p->s_id) || UpdModLine)
  418. X        des_p->s_flags = MODELINE | DIRTY;
  419. X#ifdef MAC
  420. X    if(UpdModLine) Modechange = 1;
  421. X    if(w == curwind && w->w_control) SetScrollBar(w->w_control);
  422. X#endif
  423. X}
  424. X
  425. X/* Write whatever is in mesgbuf (maybe we are Asking, or just printed
  426. X   a message).  Turns off the UpdateMesg line flag. */
  427. X
  428. void
  429. DrawMesg(abortable)
  430. X{
  431. X#ifndef MAC        /* same reason as in redisplay() */
  432. X    if (charp())
  433. X        return;
  434. X#endif
  435. X    i_set(ILI, 0);
  436. X    if (swrite(mesgbuf, NO, abortable)) {
  437. X        cl_eol();
  438. X        UpdMesg = 0;
  439. X    }
  440. X    flusho();
  441. X}
  442. X
  443. X/* Goto the current position in the current window.  Presumably redisplay()
  444. X   has already been called, and curwind->{w_dotline,w_dotcol} have been set
  445. X   correctly. */
  446. X
  447. private void
  448. GotoDot()
  449. X{
  450. X    if (InputPending)
  451. X        return;
  452. X    Placur(curwind->w_dotline, curwind->w_dotcol -
  453. X                PhysScreen[curwind->w_dotline].s_offset);
  454. X    flusho();
  455. X}
  456. X
  457. private int
  458. UntilEqual(start)
  459. register int    start;
  460. X{
  461. X    register struct scrimage    *des_p = &DesiredScreen[start],
  462. X                    *phys_p = &PhysScreen[start];
  463. X
  464. X    while ((start < ILI) && (des_p->s_id != phys_p->s_id)) {
  465. X        des_p += 1;
  466. X        phys_p += 1;
  467. X        start += 1;
  468. X    }
  469. X
  470. X    return start;
  471. X}
  472. X
  473. X/* Calls the routine to do the physical changes, and changes PhysScreen to
  474. X   reflect those changes. */
  475. X
  476. private int
  477. AddLines(at, num)
  478. register int    at,
  479. X        num;
  480. X{
  481. X    register int    i;
  482. X    int    bottom = UntilEqual(at + num);
  483. X
  484. X    if (num == 0 || num >= ((bottom - 1) - at))
  485. X        return NO;                /* we did nothing */
  486. X    v_ins_line(num, at, bottom - 1);
  487. X
  488. X    /* Now change PhysScreen to account for the physical change. */
  489. X
  490. X    for (i = bottom - 1; i - num >= at; i--)
  491. X        PhysScreen[i] = PhysScreen[i - num];
  492. X    for (i = 0; i < num; i++)
  493. X        PhysScreen[at + i].s_id = 0;
  494. X    return YES;                    /* we did something */
  495. X}
  496. X
  497. private int
  498. DelLines(at, num)
  499. register int    at,
  500. X        num;
  501. X{
  502. X    register int    i;
  503. X    int    bottom = UntilEqual(at + num);
  504. X
  505. X    if (num == 0 || num >= ((bottom - 1) - at))
  506. X        return NO;
  507. X    v_del_line(num, at, bottom - 1);
  508. X
  509. X    for (i = at; num + i < bottom; i++)
  510. X        PhysScreen[i] = PhysScreen[num + i];
  511. X    for (i = bottom - num; i < bottom; i++)
  512. X        PhysScreen[i].s_id = 0;
  513. X    return YES;
  514. X}
  515. X
  516. X/* Update line linenum in window w.  Only set PhysScreen to DesiredScreen
  517. X   if the swrite or cl_eol works, that is nothing is interupted by 
  518. X   characters typed. */ 
  519. X
  520. private void
  521. UpdLine(linenum)
  522. register int    linenum;
  523. X{
  524. X    register struct scrimage    *des_p = &DesiredScreen[linenum];
  525. X    register Window    *w = des_p->s_window;
  526. X
  527. X    i_set(linenum, 0);
  528. X    if (des_p->s_flags & MODELINE)
  529. X        ModeLine(w);
  530. X    else if (des_p->s_id) {
  531. X        des_p->s_lp->l_dline &= ~DIRTY;
  532. X        des_p->s_flags &= ~(DIRTY | L_MOD);
  533. X#ifdef ID_CHAR
  534. X        if (!UseIC && (w->w_flags & W_NUMLINES))
  535. X#else
  536. X        if (w->w_flags & W_NUMLINES)
  537. X#endif
  538. X            (void) swrite(sprint("%6d  ", des_p->s_vln), NO, YES);
  539. X
  540. X#ifdef ID_CHAR
  541. X        if (UseIC) {
  542. X            char    outbuf[MAXCOLS],
  543. X                *lptr;
  544. X            int    fromcol = (w->w_flags & W_NUMLINES) ? 8 : 0;
  545. X
  546. X            if (w->w_flags & W_NUMLINES)
  547. X                sprintf(outbuf, "%6d  ", des_p->s_vln);
  548. X            lptr = lcontents(des_p->s_lp);
  549. X            DeTab(des_p->s_offset, lptr, outbuf + fromcol,
  550. X                (sizeof outbuf) - 1 - fromcol,
  551. X                des_p->s_window->w_flags & W_VISSPACE);
  552. X            if (IDchar(outbuf, linenum, 0))
  553. X                PhysScreen[linenum] = *des_p;
  554. X            else if (i_set(linenum, 0), swrite(outbuf, NO, YES))
  555. X                do_cl_eol(linenum);
  556. X            else
  557. X                PhysScreen[linenum].s_id = -1;
  558. X        } else
  559. X#endif /* ID_CHAR */
  560. X            if (BufSwrite(linenum))
  561. X            do_cl_eol(linenum);
  562. X        else
  563. X            PhysScreen[linenum].s_id = -1;
  564. X    } else if (PhysScreen[linenum].s_id)    /* not the same ... make sure */
  565. X        do_cl_eol(linenum);
  566. X}
  567. X
  568. private void
  569. do_cl_eol(linenum)
  570. register int    linenum;
  571. X{
  572. X    cl_eol();
  573. X    PhysScreen[linenum] = DesiredScreen[linenum];
  574. X}
  575. X
  576. X#ifdef ID_CHAR
  577. X
  578. X/* From here to the end of the file is code that tries to utilize the
  579. X   insert/delete character feature on some terminals.  It is very confusing
  580. X   and not so well written code, AND there is a lot of it.  You may want
  581. X   to use the space for something else. */
  582. X
  583. extern struct screenline    *Screen;
  584. int    IN_INSmode = 0;
  585. X
  586. int    UseIC;
  587. X
  588. int    DClen,
  589. X    MDClen,
  590. X    IClen,
  591. X    MIClen,
  592. X    IMlen,
  593. X    CElen;
  594. X
  595. void
  596. disp_opt_init()
  597. X{
  598. X    DClen = DC ? strlen(DC) : 0;
  599. X    MDClen = M_DC ? strlen(M_DC) : 9999;
  600. X    IClen = IC ? strlen(IC) : 0;
  601. X    MIClen = M_IC ? strlen(M_IC) : 9999;
  602. X    IMlen = IM ? strlen(IM) : 0;
  603. X    CElen = CE ? strlen(CE) : 0;
  604. X
  605. X    UseIC = (IC || IM || M_IC);
  606. X}
  607. X
  608. void
  609. INSmode(on)
  610. X{
  611. X    if (on && !IN_INSmode) {
  612. X        putpad(IM, 1);
  613. X        IN_INSmode = YES;
  614. X    } else if (!on && IN_INSmode) {
  615. X        putpad(EI, 1);
  616. X        IN_INSmode = NO;
  617. X    }
  618. X}
  619. X
  620. private void
  621. DeTab(s_offset, buf, outbuf, limit, visspace)
  622. register char    *buf;
  623. char    *outbuf;
  624. X{
  625. X    register char    *phys_p = outbuf,
  626. X            c;
  627. X    register int    pos = 0;
  628. X    char        *limitp = &outbuf[limit];
  629. X
  630. X#define OkayOut(ch)    if ((pos++ >= s_offset) && (phys_p < limitp))\
  631. X                *phys_p++ = ch;\
  632. X            else
  633. X
  634. X    while (c = *buf++) {
  635. X        if (c == '\t') {
  636. X            int    nchars = (tabstop - (pos % tabstop));
  637. X
  638. X            if (visspace) {
  639. X                OkayOut('>');
  640. X                nchars -= 1;
  641. X            }
  642. X            while (--nchars >= 0)
  643. X                OkayOut(' ');
  644. X
  645. X        } else if (isctrl(c)) {
  646. X            OkayOut('^');
  647. X            OkayOut(c == 0177 ? '?' : c + '@');
  648. X        } else {
  649. X            if (visspace && c == ' ')
  650. X                c = '_';
  651. X            OkayOut(c);
  652. X        }
  653. X        if (pos - s_offset >= CO) {
  654. X            phys_p = &outbuf[CO - 1];
  655. X            *phys_p++ = '!';
  656. X            break;
  657. X        }            
  658. X    }
  659. X    *phys_p = 0;
  660. X}
  661. X
  662. X/* ID character routines full of special cases and other fun stuff like that.
  663. X   It actually works though ... 
  664. X
  665. X      Returns Non-Zero if you are finished (no differences left). */
  666. X
  667. private int
  668. IDchar(new, lineno, col)
  669. register char    *new;
  670. X{
  671. X    register int    i;
  672. X    int    j,
  673. X        oldlen,
  674. X        NumSaved;
  675. X    register struct screenline    *sline = &Screen[lineno];
  676. X
  677. X    oldlen = sline->s_length - sline->s_line;
  678. X
  679. X    for (i = col; i < oldlen && new[i] != 0; i++)
  680. X        if (sline->s_line[i] != new[i])
  681. X            break;
  682. X    if (new[i] == 0 || i == oldlen)
  683. X        return (new[i] == 0 && i == oldlen);
  684. X
  685. X    for (j = i + 1; j < oldlen && new[j]; j++) {
  686. X        if (new[j] == sline->s_line[i]) {
  687. X            NumSaved = IDcomp(new + j, sline->s_line + i,
  688. X                    strlen(new)) + NumSimilar(new + i,
  689. X                        sline->s_line + i, j - i);
  690. X            if (OkayInsert(NumSaved, j - i)) {
  691. X                InsChar(lineno, i, j - i, new);
  692. X                return(IDchar(new, lineno, j));
  693. X            }
  694. X        }
  695. X    }
  696. X
  697. X    for (j = i + 1; j < oldlen && new[i]; j++) {
  698. X        if (new[i] == sline->s_line[j]) {
  699. X            NumSaved = IDcomp(new + i, sline->s_line + j,
  700. X                    oldlen - j);
  701. X            if (OkayDelete(NumSaved, j - i, new[oldlen] == 0)) {
  702. X                DelChar(lineno, i, j - i);
  703. X                return(IDchar(new, lineno, j));
  704. X            }
  705. X        }
  706. X    }
  707. X    return 0;
  708. X}
  709. X
  710. private int
  711. NumSimilar(s, t, n)
  712. register char    *s,
  713. X        *t;
  714. X{
  715. X    register int    num = 0;
  716. X
  717. X    while (n--)
  718. X        if (*s++ == *t++)
  719. X            num += 1;
  720. X    return num;
  721. X}
  722. X
  723. private int
  724. IDcomp(s, t, len)
  725. register char    *s,
  726. X        *t;
  727. X{
  728. X    register int    i;
  729. X    int    num = 0,
  730. X        nonspace = 0;
  731. X    char    c;
  732. X
  733. X    for (i = 0; i < len; i++) {
  734. X        if ((c = *s++) != *t++)
  735. X            break;
  736. X        if (c != ' ')
  737. X            nonspace++;
  738. X        if (nonspace)
  739. X            num += 1;
  740. X    }
  741. X
  742. X    return num;
  743. X}
  744. X
  745. private int
  746. OkayDelete(Saved, num, samelength)
  747. X{
  748. X    /* If the old and the new are the same length, then we don't
  749. X     * have to clear to end of line.  We take that into consideration.
  750. X     */
  751. X    return ((Saved + (!samelength ? CElen : 0))
  752. X        > min(MDClen, DClen * num));
  753. X}
  754. X
  755. private int
  756. OkayInsert(Saved, num)
  757. X{
  758. X    register int    n = 0;
  759. X
  760. X    if (IC)        /* Per character prefixes */
  761. X        n = min(num * IClen, MIClen);
  762. X
  763. X    if (IM && !IN_INSmode) {    
  764. X        /* Good terminal.  Fewer characters in this case */
  765. X        n += IMlen;
  766. X    }
  767. X
  768. X    n += num;    /* The characters themselves */
  769. X
  770. X    return Saved > n;
  771. X}
  772. X
  773. extern int    CapCol;
  774. extern char    *cursend;
  775. extern struct screenline    *Curline;
  776. X
  777. private void
  778. DelChar(lineno, col, num)
  779. X{
  780. X    register char    *from,
  781. X            *to;
  782. X    register int    i;
  783. X    struct screenline *sp = (&Screen[lineno]);
  784. X
  785. X    Placur(lineno, col);
  786. X    if (M_DC && num > 1) {
  787. X        char    minibuf[16];
  788. X
  789. X        sprintf(minibuf, M_DC, num);
  790. X        putpad(minibuf, num);
  791. X    } else {
  792. X        for (i = num; --i >= 0; )
  793. X            putpad(DC, 1);
  794. X    }
  795. X
  796. X    to = sp->s_line + col;
  797. X    from = to + num;
  798. X
  799. X    byte_copy(from, to, sp->s_length - from + 1);
  800. X    clrline(sp->s_length - num, sp->s_length);
  801. X    sp->s_length -= num;
  802. X}
  803. X
  804. private void
  805. InsChar(lineno, col, num, new)
  806. char    *new;
  807. X{
  808. X    register char    *sp1,
  809. X            *sp2,    /* To push over the array. */
  810. X            *sp3;    /* Last character to push over. */
  811. X    int    i;
  812. X
  813. X    i_set(lineno, 0);
  814. X    sp2 = Curline->s_length + num;
  815. X
  816. X    if (sp2 >= cursend) {
  817. X        i_set(lineno, CO - num - 1);
  818. X        cl_eol();
  819. X        sp2 = cursend - 1;
  820. X    }
  821. X    Curline->s_length = sp2;
  822. X    sp1 = sp2 - num;
  823. X    sp3 = Curline->s_line + col;
  824. X
  825. X    while (sp1 >= sp3)
  826. X        *sp2-- = *sp1--;
  827. X
  828. X    new += col;
  829. X    byte_copy(new, sp3, num);
  830. X    /* The internal screen is correct, and now we have to do
  831. X       the physical stuff. */
  832. X
  833. X    Placur(lineno, col);
  834. X    if (IM) {
  835. X        if (!IN_INSmode)
  836. X            INSmode(1);
  837. X    } else if (M_IC && num > 1) {
  838. X        char    minibuf[16];
  839. X
  840. X        sprintf(minibuf, M_IC, num);
  841. X        putpad(minibuf, num);
  842. X    } else if (IC) {
  843. X        for (i = 0; i < num; i++)
  844. X            putpad(IC, 1);
  845. X    }
  846. X    for (i = 0; i < num; i++) {
  847. X        putchar(new[i]);
  848. X        if (IN_INSmode)
  849. X            putpad(IP, 1);
  850. X    }
  851. X    CapCol += num;
  852. X}
  853. X
  854. X#endif /* ID_CHAR */
  855. X
  856. X#ifdef UNIX        /* obviously ... no mail today if not Unix*/
  857. X
  858. X/* chkmail() returns nonzero if there is new mail since the
  859. X   last time we checked. */
  860. X
  861. char    Mailbox[FILESIZE];    /* initialized in main */
  862. int    MailInt = 60;    /* check no more often than 60 seconds */
  863. X#ifdef BIFF
  864. int    BiffChk = NO;    /* whether or not to turn off biff while in JOVE */
  865. X#endif
  866. X
  867. int
  868. chkmail(force)
  869. X{
  870. X    time_t    now;
  871. X    static time_t    last_chk = 0;
  872. X    static int    value = FALSE;
  873. X    static off_t    last_size = 0;
  874. X    struct stat    stbuf;
  875. X    int    last_val;
  876. X    static time_t    last_time = 0;
  877. X
  878. X    time(&now);
  879. X    if (!force && (now < last_chk + MailInt))
  880. X        return value;
  881. X    last_chk = now;
  882. X    if (force)
  883. X        last_time = now;
  884. X    if (stat(Mailbox, &stbuf) < 0) {
  885. X        value = FALSE;
  886. X        return FALSE;
  887. X    }
  888. X    last_val = value;
  889. X    value = ((stbuf.st_mtime > last_time) &&
  890. X         (stbuf.st_size > 0) &&
  891. X         (stbuf.st_size >= last_size) &&
  892. X         (stbuf.st_mtime + 5 > stbuf.st_atime));
  893. X    if (value == TRUE &&
  894. X              ((value != last_val) || (stbuf.st_size != last_size)))
  895. X        dobell(3);
  896. X    if (stbuf.st_size < last_size)
  897. X        last_time = now;
  898. X    last_size = stbuf.st_size;
  899. X    return value;
  900. X}
  901. X
  902. X#endif /* UNIX */
  903. X
  904. X/* Print the mode line. */
  905. X
  906. private char    *mode_p,
  907. X        *mend_p;
  908. int    BriteMode = 1;        /* modeline should standout */
  909. X
  910. private void
  911. mode_app(str)
  912. register char    *str;
  913. X{
  914. X    if (mode_p >= mend_p)
  915. X        return;
  916. X    while ((mode_p < mend_p) && (*mode_p++ = *str++))
  917. X        ;
  918. X    mode_p -= 1;    /* back over the null */
  919. X}
  920. X
  921. char    ModeFmt[120] = "%3c %w %[%sJOVE (%M)   Buffer: %b  \"%f\" %]%s%m*- %((%t)%s%)%e";
  922. X
  923. private void
  924. ModeLine(w)
  925. register Window    *w;
  926. X{
  927. X    extern int    i_line;
  928. X    extern char    *pwd();
  929. X    int    n,
  930. X        ign_some = NO;
  931. X    char    line[MAXCOLS],
  932. X        *fmt = ModeFmt,
  933. X        fillc,
  934. X        c;
  935. X    register Buffer    *thisbuf = w->w_bufp;
  936. X    register Buffer *bp;
  937. X
  938. X    mode_p = line;
  939. X    mend_p = &line[(sizeof line) - 1];
  940. X
  941. X#if defined(UNIX) || (defined (MSDOS) && !defined(IBMPC))
  942. X    if (BriteMode != 0 && SO == 0)
  943. X        BriteMode = 0;
  944. X    fillc = BriteMode ? ' ' : '-';
  945. X#endif /* UNIX */
  946. X#ifdef IBMPC        /* very subtle - don't mess up attributes too much */
  947. X    fillc = '-'; /*BriteMode ? ' ' : '-';*/
  948. X#endif /* IBMPC */
  949. X#ifdef MAC
  950. X    fillc = '_';    /* looks better on a Mac */
  951. X#endif /* MAC */
  952. X
  953. X    while (c = *fmt++) {
  954. X        if (c != '%') {
  955. X            if (c == '\\')
  956. X                if ((c = *fmt++) == '\0')
  957. X                    break;
  958. X            if (!ign_some)
  959. X                *mode_p++ = c;
  960. X            continue;
  961. X        }
  962. X        if ((c = *fmt++) == '\0')    /* char after the '%' */
  963. X            break;
  964. X        if (ign_some && c != ')')
  965. X            continue;
  966. X        n = 1;
  967. X        if (c >= '0' && c <= '9') {
  968. X            n = 0;
  969. X            while (c >= '0' && c <= '9') {
  970. X                n = n * 10 + (c - '0');
  971. X                c = *fmt++;
  972. X            }
  973. X        }
  974. X        switch (c) {
  975. X        case '(':
  976. X            if (w->w_next != fwind)    /* Not bottom window. */
  977. X                ign_some = YES;
  978. X            break;
  979. X
  980. X        case ')':
  981. X            ign_some = NO;
  982. X            break;
  983. X
  984. X        case '[':
  985. X        case ']':
  986. X            {
  987. X                char    *strs = (c == '[') ? "[[[[[[[[[[" : "]]]]]]]]]]";
  988. X
  989. X                mode_app(strs + 10 - RecDepth);
  990. X            break;
  991. X            }
  992. X            
  993. X#ifdef UNIX
  994. X        case 'C':    /* check mail here */
  995. X            if (chkmail(NO))
  996. X                mode_app("[New mail]");
  997. X            break;
  998. X
  999. X#endif /* UNIX */
  1000. X
  1001. X        case 'M':
  1002. X            {
  1003. X                static char    *mmodes[] = {
  1004. X                "Fundamental ",
  1005. X                "Text ",
  1006. X                "C ",
  1007. X#ifdef LISP
  1008. X                "Lisp ",
  1009. X#endif
  1010. X                0
  1011. X            };
  1012. X
  1013. X                mode_app(mmodes[thisbuf->b_major]);
  1014. X
  1015. X            if (BufMinorMode(thisbuf, Fill))
  1016. X                mode_app("Fill ");
  1017. X            if (BufMinorMode(thisbuf, Abbrev))
  1018. X                mode_app("Abbrev ");
  1019. X            if (BufMinorMode(thisbuf, OverWrite))
  1020. X                mode_app("OvrWt ");
  1021. X            if (BufMinorMode(thisbuf, Indent))
  1022. X                mode_app("AI ");
  1023. X            if (InMacDefine)
  1024. X                mode_app("Def ");
  1025. X            mode_p -= 1;    /* Back over the extra space. */
  1026. X            break;
  1027. X            }
  1028. X
  1029. X        case 'c':
  1030. X            while (--n >= 0)
  1031. X                *mode_p++ = fillc;
  1032. X            break;
  1033. X
  1034. X#ifdef CHDIR
  1035. X        case 'd':    /* print working directory */
  1036. X            mode_app(pr_name(pwd(), YES));
  1037. X            break;
  1038. X#endif
  1039. X            
  1040. X        case 'e':
  1041. X            {
  1042. X            /* 2 space pad pluss padding for magic cookies */
  1043. X            char    *last_p = &line[CO - 2 - (2 * SG)];
  1044. X
  1045. X            while (mode_p < last_p)
  1046. X                *mode_p++ = fillc;
  1047. X
  1048. X                goto outahere;        /* %e means we're done! */
  1049. X            }
  1050. X
  1051. X        case 'b':
  1052. X            mode_app(thisbuf->b_name);
  1053. X            break;
  1054. X
  1055. X        case 'f':
  1056. X        case 'F':
  1057. X            if (thisbuf->b_fname == 0)
  1058. X                mode_app("[No file]");
  1059. X            else {
  1060. X                if (c == 'f')
  1061. X                    mode_app(pr_name(thisbuf->b_fname, YES));
  1062. X                else
  1063. X                    mode_app(basename(thisbuf->b_fname));
  1064. X            }
  1065. X            break;
  1066. X
  1067. X#ifdef LOAD_AV
  1068. X        case 'l':
  1069. X            {
  1070. X            double    theavg;
  1071. X                char    minibuf[10];
  1072. X
  1073. X                get_la(&theavg);
  1074. X                theavg += .005;    /* round to nearest .01 */
  1075. X                sprintf(minibuf, "%d.%02d",
  1076. X                   (int) theavg,
  1077. X                   (int)((theavg - (int) theavg) * 100));
  1078. X                mode_app(minibuf);
  1079. X            break;
  1080. X            }
  1081. X#endif
  1082. X
  1083. X        case 'm':
  1084. X            if (IsModified(w->w_bufp))
  1085. X                *mode_p++ = fmt[0];
  1086. X            else
  1087. X                *mode_p++ = fmt[1];
  1088. X            fmt += 2;    /* skip two characters */
  1089. X            break;
  1090. X
  1091. X        case 'n':
  1092. X            {
  1093. X            char    tmp[16];
  1094. X            for (bp = world, n = 1; bp != 0; bp = bp->b_next, n++)
  1095. X                if (bp == thisbuf)
  1096. X                    break;
  1097. X
  1098. X            sprintf(tmp, "%d", n);
  1099. X            mode_app(tmp);
  1100. X            break;
  1101. X            }
  1102. X
  1103. X#ifdef IPROCS
  1104. X        case 'p':
  1105. X            if (thisbuf->b_type == B_PROCESS) {
  1106. X            char    tmp[40];
  1107. X
  1108. X            sprintf(tmp, "(%s)", (thisbuf->b_process == 0) ?
  1109. X                         "No process" :
  1110. X                         pstate(thisbuf->b_process));
  1111. X            mode_app(tmp);
  1112. X            break;
  1113. X            }
  1114. X#endif
  1115. X
  1116. X        case 's':
  1117. X            if (mode_p[-1] == ' ')
  1118. X                continue;
  1119. X            *mode_p++ = ' ';
  1120. X            break;
  1121. X
  1122. X        case 't':
  1123. X            {
  1124. X            char    timestr[12];
  1125. X
  1126. X                mode_app(get_time((time_t *) 0, timestr, 11, 16));
  1127. X            break;
  1128. X            }
  1129. X
  1130. X        case 'w':
  1131. X            if (w->w_LRscroll > 0) 
  1132. X                mode_app(">");
  1133. X        }
  1134. X    }
  1135. X
  1136. outahere:
  1137. X    *mode_p = 0;
  1138. X
  1139. X    /* Highlight mode line. */
  1140. X    if (BriteMode) {
  1141. X#ifdef ID_CHAR
  1142. X        if (IN_INSmode)
  1143. X            INSmode(0);
  1144. X#endif
  1145. X#ifdef TERMCAP
  1146. X        putpad(SO, 1);
  1147. X#else 
  1148. X        SO_on();
  1149. X#endif /* TERMCAP */
  1150. X    }
  1151. X    if (swrite(line, BriteMode, YES))
  1152. X        do_cl_eol(i_line);
  1153. X    else
  1154. X        UpdModLine = 1;
  1155. X    if (BriteMode)
  1156. X#ifdef TERMCAP
  1157. X        putpad(SE, 1);
  1158. X#else 
  1159. X        SO_off();
  1160. X#endif /* TERMCAP */
  1161. X}
  1162. X
  1163. X/* This tries to place the current line of the current window in the
  1164. X   center of the window, OR to place it at the arg'th line of the window.
  1165. X   This also causes the horizontal position of the line to be centered,
  1166. X   if the line needs scrolling, or moved all the way back to the left,
  1167. X   if that's possible. */
  1168. void
  1169. RedrawDisplay()
  1170. X{
  1171. X    int    line;
  1172. X    Line    *newtop = prev_line((curwind->w_line = curline), is_an_arg() ?
  1173. X                arg_value() : HALF(curwind));
  1174. X
  1175. X    if ((line = in_window(curwind, curwind->w_line)) != -1)
  1176. X        PhysScreen[line].s_offset = -1;
  1177. X    if (newtop == curwind->w_top)
  1178. X        v_clear(FLine(curwind), FLine(curwind) + SIZE(curwind));
  1179. X    else
  1180. X        SetTop(curwind, newtop);
  1181. X}
  1182. X
  1183. void
  1184. v_clear(line1, line2)
  1185. register int    line1;
  1186. X{
  1187. X    register struct scrimage    *phys_p, *des_p;
  1188. X
  1189. X    phys_p = &PhysScreen[line1];
  1190. X    des_p = &DesiredScreen[line1];
  1191. X
  1192. X    while (line1 <= line2) {
  1193. X        i_set(line1, 0);
  1194. X        cl_eol();
  1195. X        phys_p->s_id = des_p->s_id = 0;
  1196. X        phys_p += 1;
  1197. X         des_p += 1;
  1198. X        line1 += 1;
  1199. X    }
  1200. X}
  1201. X
  1202. void
  1203. ClAndRedraw()
  1204. X{
  1205. X    cl_scr(YES);
  1206. X}
  1207. X
  1208. void
  1209. NextPage()
  1210. X{
  1211. X    Line    *newline;
  1212. X
  1213. X    if (Asking)
  1214. X        return;
  1215. X    if (arg_value() < 0) {
  1216. X        negate_arg_value();
  1217. X        PrevPage();
  1218. X        return;
  1219. X    }
  1220. X    if (arg_type() == YES)
  1221. X        UpScroll();
  1222. X    else {
  1223. X        if (in_window(curwind, curwind->w_bufp->b_last) != -1) {
  1224. X            rbell();
  1225. X            return;
  1226. X        }
  1227. X        newline = next_line(curwind->w_top, max(1, SIZE(curwind) - 1));
  1228. X        SetTop(curwind, curwind->w_line = newline);
  1229. X        if (curwind->w_bufp == curbuf)
  1230. X            SetLine(newline);
  1231. X    }
  1232. X}
  1233. X
  1234. X#ifdef MSDOS        /* kg */
  1235. X
  1236. void
  1237. PageScrollUp()
  1238. X{
  1239. X    int i, n;
  1240. X
  1241. X    n = max(1, SIZE(curwind) - 1);
  1242. X    for (i=0; i<n; i++) {
  1243. X        UpScroll();
  1244. X        redisplay();
  1245. X    }
  1246. X}
  1247. X
  1248. void
  1249. PageScrollDown()
  1250. X{
  1251. X       int i, n;
  1252. X
  1253. X    n = max(1, SIZE(curwind) - 1);
  1254. X    for (i=0; i<n; i++) {
  1255. X        DownScroll();
  1256. X        redisplay();
  1257. X    }
  1258. X}
  1259. X#endif /* MSDOS */
  1260. X
  1261. void
  1262. PrevPage()
  1263. X{
  1264. X    Line    *newline;
  1265. X
  1266. X    if (Asking)
  1267. X        return;
  1268. X    if (arg_value() < 0) {
  1269. X        negate_arg_value();
  1270. X        NextPage();
  1271. X        return;
  1272. X    }
  1273. X    if (arg_type() == YES)
  1274. X        DownScroll();
  1275. X    else {
  1276. X        newline = prev_line(curwind->w_top, max(1, SIZE(curwind) - 1));
  1277. X        SetTop(curwind, curwind->w_line = newline);
  1278. X        if (curwind->w_bufp == curbuf)
  1279. X            SetLine(newline);
  1280. X    }
  1281. X}
  1282. X
  1283. void
  1284. UpScroll()
  1285. X{
  1286. X    SetTop(curwind, next_line(curwind->w_top, arg_value()));
  1287. X    if ((curwind->w_bufp == curbuf) &&
  1288. X        (in_window(curwind, curline) == -1))
  1289. X        SetLine(curwind->w_top);
  1290. X}
  1291. X
  1292. void
  1293. DownScroll()
  1294. X{
  1295. X    SetTop(curwind, prev_line(curwind->w_top, arg_value()));
  1296. X    if ((curwind->w_bufp == curbuf) &&
  1297. X        (in_window(curwind, curline) == -1))
  1298. X        SetLine(curwind->w_top);
  1299. X}
  1300. X
  1301. int    VisBell = NO,
  1302. X    RingBell = NO;    /* So if we have a lot of errors ...
  1303. X               ring the bell only ONCE */
  1304. void
  1305. rbell()
  1306. X{
  1307. X    RingBell = YES;
  1308. X}
  1309. X
  1310. X/* Message prints the null terminated string onto the bottom line of the
  1311. X   terminal. */
  1312. X
  1313. void
  1314. message(str)
  1315. char    *str;
  1316. X{
  1317. X    if (InJoverc)
  1318. X        return;
  1319. X    UpdMesg = YES;
  1320. X    errormsg = NO;
  1321. X    if (str != mesgbuf)
  1322. X        null_ncpy(mesgbuf, str, (sizeof mesgbuf) - 1);
  1323. X}
  1324. X
  1325. X/* End of Window */
  1326. X
  1327. void
  1328. Eow()
  1329. X{
  1330. X    if (Asking)
  1331. X        return;
  1332. X    SetLine(next_line(curwind->w_top, SIZE(curwind) - 1 -
  1333. X            min(SIZE(curwind) - 1, arg_value() - 1)));
  1334. X    if (!is_an_arg())
  1335. X        Eol();
  1336. X}
  1337. X
  1338. X/* Beginning of Window */
  1339. X
  1340. void
  1341. Bow()
  1342. X{
  1343. X    if (Asking)
  1344. X        return;
  1345. X    SetLine(next_line(curwind->w_top, min(SIZE(curwind) - 1, arg_value() - 1)));
  1346. X}
  1347. X
  1348. private int    LineNo,
  1349. X        last_col,
  1350. X        DoAutoNL;
  1351. private Window    *old_wind;    /* save the window we were in BEFORE
  1352. X                   before we were called, if UseBuffers
  1353. X                   is nonzero */
  1354. X
  1355. int    UseBuffers = FALSE;
  1356. int    TOabort = 0;
  1357. X
  1358. X/* This initializes the typeout.  If send-typeout-to-buffers is set
  1359. X   the buffer NAME is created (emptied if it already exists) and output
  1360. X   goes to the buffer.  Otherwise output is drawn on the screen and
  1361. X   erased by TOstop() */
  1362. X
  1363. void
  1364. TOstart(name, auto_newline)
  1365. char    *name;
  1366. X{
  1367. X    if (UseBuffers) {
  1368. X        old_wind = curwind;
  1369. X        pop_wind(name, YES, B_SCRATCH);
  1370. X    } else
  1371. X        DisabledRedisplay = YES;
  1372. X    TOabort = LineNo = last_col = 0;
  1373. X    DoAutoNL = auto_newline;
  1374. X}
  1375. X
  1376. X/* VARARGS1 */
  1377. X
  1378. void
  1379. Typeout(fmt, va_alist)
  1380. char    *fmt;
  1381. va_dcl
  1382. X{
  1383. X    if (TOabort)
  1384. X        return;
  1385. X
  1386. X    if (!UseBuffers && (LineNo == ILI - 1)) {
  1387. X        register int    c;
  1388. X
  1389. X        LineNo = 0;
  1390. X        last_col = 0;
  1391. X        f_mess("--more--");
  1392. X        if ((c = getchar()) != ' ') {
  1393. X            TOabort = YES;
  1394. X            if (c != AbortChar && c != RUBOUT)
  1395. X                Ungetc(c);
  1396. X            f_mess(NullStr);
  1397. X            return;
  1398. X        }
  1399. X        f_mess(NullStr);
  1400. X    }
  1401. X
  1402. X    if (fmt) {
  1403. X        extern int    i_col;
  1404. X        char    string[132];
  1405. X        va_list    ap;
  1406. X
  1407. X        va_start(ap);
  1408. X        format(string, sizeof string, fmt, ap);
  1409. X        va_end(ap);
  1410. X        if (UseBuffers)
  1411. X            ins_str(string, NO);
  1412. X        else {
  1413. X            i_set(LineNo, last_col);
  1414. X            (void) swrite(string, NO, YES);
  1415. X            last_col = i_col;
  1416. X        }
  1417. X    }
  1418. X    if (!UseBuffers) {
  1419. X        PhysScreen[LineNo].s_id = -1;
  1420. X        if (fmt == 0 || DoAutoNL == YES) {
  1421. X            cl_eol();
  1422. X            flusho();
  1423. X            LineNo += 1;
  1424. X            last_col = 0;
  1425. X        }
  1426. X    } else if (fmt == 0 || DoAutoNL != 0)
  1427. X        ins_str("\n", NO);
  1428. X}
  1429. X
  1430. void
  1431. TOstop()
  1432. X{
  1433. X    int    c;
  1434. X
  1435. X    if (UseBuffers) {
  1436. X        ToFirst();
  1437. X        SetWind(old_wind);
  1438. X    } else {
  1439. X        if (TOabort) {
  1440. X            DisabledRedisplay = NO;
  1441. X            return;
  1442. X        }
  1443. X        if (last_col != 0)
  1444. X            Typeout((char *) 0);
  1445. X          Typeout("----------");
  1446. X        cl_eol();
  1447. X        flusho();
  1448. X        c = getchar();
  1449. X        if (c != ' ')
  1450. X            Ungetc(c);
  1451. X        DisabledRedisplay = NO;
  1452. X    }
  1453. X}
  1454. END_OF_FILE
  1455. if test 28346 -ne `wc -c <'./disp.c'`; then
  1456.     echo shar: \"'./disp.c'\" unpacked with wrong size!
  1457. fi
  1458. # end of './disp.c'
  1459. fi
  1460. echo shar: End of archive 13 \(of 21\).
  1461. cp /dev/null ark13isdone
  1462. MISSING=""
  1463. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1464.     if test ! -f ark${I}isdone ; then
  1465.     MISSING="${MISSING} ${I}"
  1466.     fi
  1467. done
  1468. if test "${MISSING}" = "" ; then
  1469.     echo You have unpacked all 21 archives.
  1470.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1471. else
  1472.     echo You still need to unpack the following archives:
  1473.     echo "        " ${MISSING}
  1474. fi
  1475. ##  End of shell archive.
  1476. exit 0
  1477.